namespace DotNetNuke.Services.Localization
{
    using DotNetNuke.Common;
    using DotNetNuke.Modules.Admin.ResourceInstaller;
    using DotNetNuke.Services.Exceptions;
    using ICSharpCode.SharpZipLib.Zip;
    using Microsoft.VisualBasic.CompilerServices;
    using System;
    using System.Collections;
    using System.IO;
    using System.Web;
    using System.Xml.Serialization;

    public class LocaleFilePackWriter
    {
        private PaLogger _ProgressLog = new PaLogger();

        private string CreateResourcePack(LocaleFilePack ResourcePack, string FileName, LanguagePackType packtype)
        {
            int CompressionLevel = 9;
            string ResPackShortName = "ResourcePack." + FileName + ".";
            if ((packtype == LanguagePackType.Core) | (packtype == LanguagePackType.Full))
            {
                ResPackShortName = ResPackShortName + "04.00.00.";
            }
            ResPackShortName = ResPackShortName + ResourcePack.LocalePackCulture.Code + ".zip";
            string ResPackName = Globals.HostMapPath + ResPackShortName;
            FileStream strmZipFile = null;
            try
            {
                this.ProgressLog.AddInfo(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.CreateArchive"), ResPackShortName));
                strmZipFile = File.Create(ResPackName);
                ZipOutputStream strmZipStream = null;
                try
                {
                    IEnumerator refObjectHelperL0=null;
                    strmZipStream = new ZipOutputStream(strmZipFile);
                    ZipEntry myZipEntry = new ZipEntry("Manifest.xml");
                    strmZipStream.PutNextEntry(myZipEntry);
                    strmZipStream.SetLevel(CompressionLevel);
                    byte[] FileData = this.GetLanguagePackManifest(ResourcePack);
                    strmZipStream.Write(FileData, 0, FileData.Length);
                    this.ProgressLog.AddInfo(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.SavedFile"), "Manifest.xml"));
                    try
                    {
                        refObjectHelperL0 = ResourcePack.Files.GetEnumerator();
                        while (refObjectHelperL0.MoveNext())
                        {
                            LocaleFileInfo LocaleFile = (LocaleFileInfo) refObjectHelperL0.Current;
                            myZipEntry = new ZipEntry(LocaleFileUtil.GetFullFileName(LocaleFile));
                            strmZipStream.PutNextEntry(myZipEntry);
                            strmZipStream.Write(LocaleFile.Buffer, 0, LocaleFile.Buffer.Length);
                            this.ProgressLog.AddInfo(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.SavedFile"), LocaleFile.LocaleFileName));
                        }
                        return ResPackName;
                    }
                    finally
                    {
                        if (refObjectHelperL0 is IDisposable)
                        {
                            (refObjectHelperL0 as IDisposable).Dispose();
                        }
                    }
                }
                catch (Exception exception1)
                {
                    
                    Exception ex = exception1;
                    DotNetNuke.Services.Exceptions.Exceptions.LogException(ex);
                    this.ProgressLog.AddFailure(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.ERROR.SavingFile"), ex));
                    
                }
                finally
                {
                    if (strmZipStream != null)
                    {
                        strmZipStream.Finish();
                        strmZipStream.Close();
                    }
                }
            }
            catch (Exception exception2)
            {
                ProjectData.SetProjectError(exception2);
                Exception ex = exception2;
                DotNetNuke.Services.Exceptions.Exceptions.LogException(ex);
                this.ProgressLog.AddFailure(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.ERROR.SavingFile"), ex));
                
            }
            finally
            {
                if (strmZipFile != null)
                {
                    strmZipFile.Close();
                }
            }
            return ResPackName;
        }

        private byte[] GetFileAsByteArray(FileInfo FileObject)
        {
            byte[] Buffer = new byte[((int) (FileObject.Length - 1L)) + 1];
            FileStream strmFile = null;
            try
            {
                strmFile = FileObject.OpenRead();
                strmFile.Read(Buffer, 0, Buffer.Length);
            }
            catch (Exception exception1)
            {
                
                Exception ex = exception1;
                DotNetNuke.Services.Exceptions.Exceptions.LogException(ex);
                this.ProgressLog.AddFailure(string.Format(DotNetNuke.Services.Localization.Localization.GetString("Log.ERROR.CreatingByteArray"), FileObject.Name, ex));
                
            }
            finally
            {
                if (strmFile != null)
                {
                    strmFile.Close();
                }
            }
            return Buffer;
        }

        private void GetGlobalResourceFiles(LocaleFileCollection ResFileList, string LocaleCode)
        {
            FileInfo[] Files;
            DirectoryInfo objFolder = new DirectoryInfo(this.GetServerPath("~/App_GlobalResources"));
            if (LocaleCode == "en-US")
            {
                Files = objFolder.GetFiles("*.resx");
                int LastIndex = Files.Length;
                Files = (FileInfo[]) Utils.CopyArray((Array) Files, new FileInfo[LastIndex + 1]);
                FileInfo TimeZoneFile = new FileInfo(Path.Combine(objFolder.FullName, "TimeZones.xml"));
                Files[LastIndex] = TimeZoneFile;
            }
            else
            {
                Files = objFolder.GetFiles("*." + LocaleCode + ".resx");
                int LastIndex = Files.Length;
                Files = (FileInfo[]) Utils.CopyArray((Array) Files, new FileInfo[LastIndex + 1]);
                Files[LastIndex] = new FileInfo(Path.Combine(objFolder.FullName, "TimeZones." + LocaleCode + ".xml"));
            }
            foreach (FileInfo objFile in Files)
            {
                if (((!objFile.Name.StartsWith("Template") && ((LocaleCode != "en-US") || ((LocaleCode == "en-US") && (objFile.Name.IndexOf('.') == objFile.Name.LastIndexOf('.'))))) ? 1 : 0) != 0)
                {
                    LocaleFileInfo LocaleFile = new LocaleFileInfo();
                    LocaleFile.LocaleFileName = objFile.Name;
                    LocaleFile.LocalePath = null;
                    LocaleFile.LocaleFileType = LocaleType.GlobalResource;
                    LocaleFile.Buffer = this.GetFileAsByteArray(objFile);
                    ResFileList.Add(LocaleFile);
                    this.ProgressLog.AddInfo(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFileName"), objFile.Name));
                }
            }
        }

        private byte[] GetLanguagePackManifest(LocaleFilePack ResourcePack)
        {
            byte[] Manifest = new byte[0];
            XmlSerializer ManifestSerializer = new XmlSerializer(typeof(LocaleFilePack));
            MemoryStream ms = new MemoryStream();
            try
            {
                ManifestSerializer.Serialize((Stream) ms, ResourcePack);
                Manifest = new byte[((int) (ms.Length - 1L)) + 1];
                ms.Position = 0L;
                ms.Read(Manifest, 0, (int) ms.Length);
                this.ProgressLog.AddInfo(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.SerializeManifest"));
            }
            catch (Exception exception1)
            {
                
                Exception ex = exception1;
                DotNetNuke.Services.Exceptions.Exceptions.LogException(ex);
                this.ProgressLog.AddFailure(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.ERROR.ManifestFile"), ex));
                
            }
            finally
            {
                ms.Close();
            }
            return Manifest;
        }

        private LocaleFileInfo GetLocaleFile(ref string RootPath, LocaleType ResType, FileInfo objFile)
        {
            LocaleFileInfo LocaleFile = new LocaleFileInfo();
            LocaleFile.LocaleFileName = objFile.Name;
            LocaleFile.LocalePath = this.StripCommonDirectory(RootPath, objFile.DirectoryName);
            LocaleFile.LocaleModule = this.GetModuleName(LocaleFile.LocalePath);
            LocaleFile.LocalePath = this.StripModuleName(LocaleFile.LocalePath, LocaleFile.LocaleModule);
            LocaleFile.LocaleFileType = ResType;
            LocaleFile.Buffer = this.GetFileAsByteArray(objFile);
            return LocaleFile;
        }

        private void GetLocalResourceFiles(LocaleFileCollection ResFileList, string RootPath, string LocaleCode, LocaleType ResType, DirectoryInfo objFolder)
        {
            FileInfo[] ascxFiles;
            FileInfo[] aspxFiles;
            if (LocaleCode == "en-US")
            {
                ascxFiles = objFolder.GetFiles("*.ascx.resx");
                aspxFiles = objFolder.GetFiles("*.aspx.resx");
            }
            else
            {
                ascxFiles = objFolder.GetFiles("*.ascx." + LocaleCode + ".resx");
                aspxFiles = objFolder.GetFiles("*.aspx." + LocaleCode + ".resx");
            }
            foreach (FileInfo objFile in ascxFiles)
            {
                ResFileList.Add(this.GetLocaleFile(ref RootPath, ResType, objFile));
                this.ProgressLog.AddInfo(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFileName"), objFile.Name));
            }
            foreach (FileInfo objFile in aspxFiles)
            {
                ResFileList.Add(this.GetLocaleFile(ref RootPath, ResType, objFile));
                this.ProgressLog.AddInfo(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFileName"), objFile.Name));
            }
        }

        private void GetLocalSharedResourceFile(LocaleFileCollection ResFileList, string RootPath, string LocaleCode, LocaleType ResType, DirectoryInfo objFolder)
        {
            string strFilePath;
            if (LocaleCode == "en-US")
            {
                strFilePath = Path.Combine(objFolder.FullName, "SharedResources.resx");
            }
            else
            {
                strFilePath = Path.Combine(objFolder.FullName, "SharedResources." + LocaleCode + ".resx");
            }
            if (File.Exists(strFilePath))
            {
                FileInfo SharedFile = new FileInfo(strFilePath);
                ResFileList.Add(this.GetLocaleFile(ref RootPath, ResType, SharedFile));
                this.ProgressLog.AddInfo(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFileName"), SharedFile.Name));
            }
        }

        public string GetModuleName(string FullPath)
        {
            string ModuleName = FullPath;
            if (ModuleName != null)
            {
                ModuleName = ModuleName.Split(new char[] { '/' })[0];
            }
            return ModuleName;
        }

        private void GetResourceFiles(LocaleFileCollection ResFileList, string BasePath, string RootPath, string LocaleCode, LocaleType ResType)
        {
            string[] folders;
            try
            {
                folders = Directory.GetDirectories(BasePath);
            }
            catch (Exception exception1)
            {
                
                
                return;
                
            }
            foreach (string folder in folders)
            {
                DirectoryInfo objFolder = new DirectoryInfo(folder);
                if (objFolder.Name == "App_LocalResources")
                {
                    this.GetLocalResourceFiles(ResFileList, RootPath, LocaleCode, ResType, objFolder);
                    this.GetLocalSharedResourceFile(ResFileList, RootPath, LocaleCode, ResType, objFolder);
                }
                else
                {
                    this.GetResourceFiles(ResFileList, folder, RootPath, LocaleCode, ResType);
                }
            }
        }

        private string GetServerPath(string RelativePath)
        {
            return HttpContext.Current.Server.MapPath(RelativePath);
        }

        private void ProcessCoreFiles(LocaleFilePack ResPack)
        {
            this.ProgressLog.StartJob(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFiles"), DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.Global")));
            this.GetGlobalResourceFiles(ResPack.Files, ResPack.LocalePackCulture.Code);
            this.ProgressLog.EndJob(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFiles"), DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.Global")));
            this.ProgressLog.StartJob(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFiles"), DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.Control")));
            this.GetResourceFiles(ResPack.Files, this.GetServerPath("~/Controls"), this.GetServerPath("~/Controls"), ResPack.LocalePackCulture.Code, LocaleType.ControlResource);
            this.ProgressLog.EndJob(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFiles"), DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.Control")));
            this.ProgressLog.StartJob(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFiles"), DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.Admin")));
            this.GetResourceFiles(ResPack.Files, this.GetServerPath("~/Admin"), this.GetServerPath("~/Admin"), ResPack.LocalePackCulture.Code, LocaleType.AdminResource);
            this.ProgressLog.EndJob(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFiles"), DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.Admin")));
        }

        private void ProcessModuleFiles(LocaleFilePack ResPack)
        {
            this.ProgressLog.StartJob(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFiles"), DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.Module")));
            this.GetResourceFiles(ResPack.Files, this.GetServerPath("~/desktopmodules"), this.GetServerPath("~/desktopmodules"), ResPack.LocalePackCulture.Code, LocaleType.LocalResource);
            this.ProgressLog.EndJob(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFiles"), DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.Module")));
        }

        private void ProcessModuleFiles(LocaleFilePack ResPack, ArrayList basefolders)
        {
            IEnumerator refObjectHelperL0=null;
            this.ProgressLog.StartJob(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFiles"), DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.Module")));
            try
            {
                refObjectHelperL0 = basefolders.GetEnumerator();
                while (refObjectHelperL0.MoveNext())
                {
                    this.GetResourceFiles(ResPack.Files, this.GetServerPath("~/desktopmodules/") + Conversions.ToString(refObjectHelperL0.Current), this.GetServerPath("~/desktopmodules"), ResPack.LocalePackCulture.Code, LocaleType.LocalResource);
                }
            }
            finally
            {
                if (refObjectHelperL0 is IDisposable)
                {
                    (refObjectHelperL0 as IDisposable).Dispose();
                }
            }
            this.ProgressLog.EndJob(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFiles"), DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.Module")));
        }

        private void ProcessProviderFiles(LocaleFilePack ResPack)
        {
            this.ProgressLog.StartJob(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFiles"), DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.Provider")));
            this.GetResourceFiles(ResPack.Files, this.GetServerPath("~/providers"), this.GetServerPath("~/providers"), ResPack.LocalePackCulture.Code, LocaleType.ProviderResource);
            this.ProgressLog.EndJob(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFiles"), DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.Provider")));
        }

        private void ProcessProviderFiles(LocaleFilePack ResPack, ArrayList basefolders)
        {
            IEnumerator refObjectHelperL0=null;
            this.ProgressLog.StartJob(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFiles"), DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.Provider")));
            try
            {
                refObjectHelperL0 = basefolders.GetEnumerator();
                while (refObjectHelperL0.MoveNext())
                {
                    this.GetResourceFiles(ResPack.Files, this.GetServerPath("~/providers/HtmlEditorProviders/") + Conversions.ToString(refObjectHelperL0.Current), this.GetServerPath("~/providers"), ResPack.LocalePackCulture.Code, LocaleType.ProviderResource);
                }
            }
            finally
            {
                if (refObjectHelperL0 is IDisposable)
                {
                    (refObjectHelperL0 as IDisposable).Dispose();
                }
            }
            this.ProgressLog.EndJob(string.Format(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.LoadFiles"), DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.Provider")));
        }

        public string SaveLanguagePack(Locale LocaleCulture, LanguagePackType packtype, ArrayList basefolders, string FileName)
        {
            LocaleFilePack ResPack = new LocaleFilePack();
            ResPack.Version = "3.0";
            ResPack.LocalePackCulture = LocaleCulture;
            switch (((int) packtype))
            {
                case 0:
                    this.ProcessCoreFiles(ResPack);
                    break;

                case 1:
                    this.ProcessModuleFiles(ResPack, basefolders);
                    break;

                case 2:
                    this.ProcessProviderFiles(ResPack, basefolders);
                    break;

                case 3:
                    this.ProcessCoreFiles(ResPack);
                    this.ProcessModuleFiles(ResPack);
                    this.ProcessProviderFiles(ResPack);
                    break;
            }
            this.ProgressLog.StartJob(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.ArchiveFiles"));
            string Result = this.CreateResourcePack(ResPack, FileName, packtype);
            this.ProgressLog.EndJob(DotNetNuke.Services.Localization.Localization.GetString("LOG.LangPack.ArchiveFiles"));
            return Result;
        }

        public string StripCommonDirectory(string RootPath, string FullPath)
        {
            string NewPath = FullPath;
            NewPath = NewPath.Replace(RootPath, "").Replace("App_LocalResources", "").Trim(new char[] { '\\', '/' });
            if (NewPath.Length == 0)
            {
                NewPath = null;
            }
            return NewPath;
        }

        public string StripModuleName(string BasePath, string ModuleName)
        {
            if ((BasePath == null) | (ModuleName == null))
            {
                return null;
            }
            string NewPath = BasePath.Replace(ModuleName, "").Trim(new char[] { '/' });
            if (NewPath.Length == 0)
            {
                NewPath = null;
            }
            return NewPath;
        }

        public PaLogger ProgressLog
        {
            get
            {
                return this._ProgressLog;
            }
        }
    }
}

